<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\Common\Mapper\RegionMapper;
use App\Common\Service\RegionService;
use App\CustHub\Mapper\ChServerMapper;
use App\CustHub\Model\ChServer;
use Hyperf\Cache\Annotation\Cacheable;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;
use Mine\Exception\NormalStatusException;



/**
 * 机器人服务器
 */
class ChServerService extends AbstractService
{
    public $mapper;

    #[Inject]
    protected RegionMapper $regionMapper;

    public function __construct(ChServerMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    public function findById(mixed $id): ChServer|Model|string|Builder|null
    {
        return $this->mapper->findById($id);
    }

    /**
     * 获取省市列表
     * @param int $level
     * @return array
     */
    #[Cacheable(prefix: 'region_list',value: 'secondary_tree_#{level}',ttl: 86400)]
    public function getSecondaryTreeList(int $level = 2): mixed
    {
        $list = $this->regionMapper->getModel()
            ->select(['id','name','pid','code','first_letter'])
            ->where(function ($query) use ($level){
                if($level == 2){
                    $query->where('level','<', 3);
                }
            })
            ->get()->toTree([],0,'id','pid');
        return $list;
    }

    /**
     * 获取服务器列表
     * @param $params
     * @return array
     */
    public function getServerList($params): array
    {
        return $this->mapper->getServerList($params);
    }

    /**
     * 新增服务器
     * @param $data
     * @return mixed
     */
    public function save($data):mixed
    {
        if ($this->mapper->checkServerIp($data['ip'])) {
            throw new NormalStatusException("IP地址已存在");
        }
        return $this->mapper->save($data);
    }

    /**
     * 更新服务器信息.
     * @param mixed $id
     * @param array $data
     * @return bool
     */
    public function update(mixed $id, array $data): bool
    {
        if ($this->mapper->checkServerIp($data['ip'],$id)) {
            throw new NormalStatusException("IP地址已被其他服务器使用");
        }
        $this->mapper->clearCache($id);
        return $this->mapper->update($id, $data);
    }

    /**
     * 单个或批量删除服务器.
     * @param array $ids
     * @return bool
     */
    public function delete(array $ids): bool
    {
        $usedServers =$this->mapper->usedServerIds($ids);
        $ids = array_diff($ids, $usedServers);
        if (empty($ids)) {
            $usedServerIds = implode(',', $usedServers);
            throw new NormalStatusException("ID为{$usedServerIds}服务器使用中无法删除");
        }
        $this->mapper->delete($ids);

        foreach ($ids as $id){
            $this->mapper->clearCache($id);
        }

        return true;
    }

    /**
     * 根据ip获取机器人所在服务器信息
     * @param string $proCode
     * @param string $cityCode
     * @param int $type
     * @return ChServer|Model|\Hyperf\Database\Query\Builder|Builder|null
     */
    public function getServerByIp(string $proCode,string $cityCode, int $type = 1): ChServer|Model|\Hyperf\Database\Query\Builder|Builder|null
    {
        // 公共查询条件
        $commonConditions = [
            'status' => 1,
            'server_status' => 1,
            'type' => $type,
        ];

        // 查询构建器
        $buildQuery = function (Builder $query) {
            $query->whereColumn('count', '<', 'max_count')
                ->orderBy('count')
                ->limit(1);
        };

        $service = ChServer::query()
            ->where($commonConditions)
            ->where('city_code',$cityCode)
            ->when(true,$buildQuery)
            ->orderBy('count')
            ->first();
        if($service){
            $service->isYd = false;
            return $service;
        }

        $service = ChServer::query()
            ->where($commonConditions)
            ->where('pro_code',$proCode)
            ->when(true,$buildQuery)
            ->orderBy('count')
            ->first();
        if($service){
            $service->isYd = false;
            return $service;
        }

        // 3. 全国随机查询
        $service = ChServer::query()
            ->where($commonConditions)
            ->when(true, $buildQuery)
            ->first();
        $service->isYd = true;
        return $service;
    }

    public function increment(mixed $id,string $column = 'count'): int
    {
        $this->mapper->clearCache($id);
        return $this->mapper->model::query()
            ->where('id',$id)
            ->increment($column);
    }

    public function decrement(mixed $id,string $column = 'count'): int
    {
        $this->mapper->clearCache($id);
        return $this->mapper->model::query()
            ->where('id',$id)
            ->decrement($column);
    }
}